package com.leyou.item.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.*;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.IBrandService;
import com.leyou.item.service.ICategoryService;
import com.leyou.item.service.IGoodsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;
import static com.leyou.common.constants.MQConstants.RoutingKey;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 处理请求和响应的方法
 *
 * @version V1.0
 * @package com.leyou.item.service.impl
 * @description:
 * @author: pc
 * @date: 2019/6/27 16:21
 */

@Service("goodsService")
public class GoodsServiceImpl implements IGoodsService {
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private IBrandService brandService;

    /**
     * 根据SpuId查询数据
     * */
    @Override
    public SpuDTO querySpuById(Long spuId) {
        //根据Id查询spu数据
        Spu spu = spuMapper.selectByPrimaryKey(spuId);
        //数据转换
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);
        //根据Id查询spu详细数据并注入spuDto
        spuDTO.setSpuDetail(querySpuDetailById(spuId));
        //根据Id查询skus
        spuDTO.setSkus(querySkuById(spuId));
        return spuDTO;
    }

    /**
     * 分页查询数据
     * */
    @Override
    public PageResult<SpuDTO> querySpuByPage(String key, Boolean saleable, Integer page, Integer rows) {

        //自动分页助手，输入分页信息
        PageHelper.startPage(page, rows);
        //过滤查询条件
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        //按照搜索条件查询
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("name", "%" + key + "%");
        }
        //是否上架
        if (saleable != null) {
            criteria.andEqualTo("saleable", (saleable));
        }
        //按照修改时间排序
        example.setOrderByClause("update_time DESC");

        //持久层查询数据
        List<Spu> list = spuMapper.selectByExample(example);
        //判空
        if (CollectionUtils.isEmpty(list)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        //解析分页信息
        PageInfo<Spu> spuPageInfo = new PageInfo<>(list);

        //数据类型转换
        List<SpuDTO> result = BeanHelper.copyWithCollection(list, SpuDTO.class);

        handleCategoryAndBrandName(result);

        return new PageResult<>(spuPageInfo.getTotal(),spuPageInfo.getPages(), result);
    }

    private void handleCategoryAndBrandName(List<SpuDTO> list) {
        for (SpuDTO spu : list) {
            // 查询分类
            String categoryName = categoryService.queryCategoryByIds(spu.getCategoryIds())
                    .stream()
                    .map(CategoryDTO::getName).collect(Collectors.joining("/"));
            spu.setCategoryName(categoryName);
            // 查询品牌
            BrandDTO brand = brandService.queryById(spu.getBrandId());
            spu.setBrandName(brand.getName());
        }
    }

    @Override
    @Transactional(rollbackFor = LyException.class)
    public void saveGoods(SpuDTO spuDTO) {

        //spu数据的提取
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setId(null);
        spu.setCreateTime(null);
        spu.setUpdateTime(null);
        //spu数据的保存
        int spuCount = spuMapper.insertSelective(spu);
        if (spuCount != 1) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

        //spuDetail数据提取
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        //spuDetail数据保存
        int detailCount = spuDetailMapper.insertSelective(spuDetail);
        if (detailCount != 1) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

        //sku的数据提取
        List<SkuDTO> skus = spuDTO.getSkus();
        List<Sku> skuList = new ArrayList<>();
        for (SkuDTO skuDTO : skus) {
            skuDTO.setSpuId(spu.getId());
            Sku sku = BeanHelper.copyProperties(skuDTO, Sku.class);
            skuList.add(sku);
        }
        //保存数据
        int skuCount = skuMapper.insertList(skuList);
        if (skuCount != skuList.size()) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }


    @Autowired
    private AmqpTemplate amqpTemplate;
    /**
     * 商品的上下架
     */
    @Override
    @Transactional(rollbackFor = LyException.class)
    public void putGoods(Long id, Boolean saleable) {
        //更新spu
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        //更新sku的Enable
        Sku sku = new Sku();
        sku.setEnable(saleable);
        //定义筛选条件
        Example example = new Example(Sku.class);
        example.createCriteria().andEqualTo("spuId",id);
        //修改数据
        int skuCount = skuMapper.updateByExampleSelective(sku, example);
        //查改需要修改的数据总数
        int size = skuMapper.selectCountByExample(example);
        //判断修改数据是否和总数相同
        if (skuCount != size) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        //发送消息
        //做了MQConstants.Routing的静态导入，所以可以不写MQConstants，直接使用Routing
        String routingKey = saleable? RoutingKey.ITEM_UP_KEY : RoutingKey.ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(MQConstants.Exchange.ITEM_EXCHANGE_NAME,routingKey,id);
    }

    @Override
    public SpuDetailDTO querySpuDetailById(Long id) {

        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(id);

        if (spuDetail == null) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }

        return BeanHelper.copyProperties(spuDetail,SpuDetailDTO.class);
    }

    @Override
    public List<SkuDTO> querySkuById(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> list = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(list)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(list,SkuDTO.class);
    }

    @Override
    public void updateGoods(SpuDTO spuDTO) {
        //判断请求参数是否有误
        Long spuId = spuDTO.getId();
        if (spuId == null) {
            throw new LyException(ExceptionEnum.INVALID_PARAM_ERROR);
        }
        Sku sku = new Sku();
        sku.setSpuId(spuId);
        //删除sku数据
        //查询sku数据的数量
        int skuCount = skuMapper.selectCount(sku);
        //数量大于0就删除
        if (skuCount > 0) {
            int deleteCount = skuMapper.delete(sku);

            if (deleteCount != skuCount) {
                throw new LyException(ExceptionEnum.DELETE_OPERATION_FAIL);
            }
        }

        //修改spu数据
        Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
        spu.setSaleable(null);
        spu.setUpdateTime(null);
        spu.setCreateTime(null);

        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        //修改spuDetail数据
        SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
        spu.setSaleable(null);
        spu.setUpdateTime(null);
        spu.setCreateTime(null);
        count = spuDetailMapper.updateByPrimaryKeySelective(spuDetail);
        if (count != 1) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        // 修改sku数据
        List<SkuDTO> skus = spuDTO.getSkus();
        List<Sku> skuList = BeanHelper.copyWithCollection(skus, Sku.class);
        for (Sku sku1 : skuList) {
            sku1.setSpuId(spuId);
            sku1.setEnable(false);
        }
        count = skuMapper.insertList(skuList);
        if (count != skuList.size()) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    /**
     * 根据id批量查询sku
     * @param ids skuId的集合
     * @return sku的集合
     */
    @Override
    public List<SkuDTO> querySkuListByIds(List<Long> ids) {
        // 查询sku
        List<Sku> skuList = skuMapper.selectByIdList(ids);
        if(CollectionUtils.isEmpty(skuList)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skuList, SkuDTO.class);
    }

    @Override
    @Transactional(rollbackFor = LyException.class)
    public void minusStock(Map<Long, Integer> cartMap) {
        for (Map.Entry<Long, Integer> entry : cartMap.entrySet()) {
            //获得购物车商品id
            Long skuId = entry.getKey();
            //获得购物车商品数量
            Integer num = entry.getValue();
            int count = skuMapper.minusStock(skuId,num);
            if (count != 1) {
                throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
            }
        }
    }
}
